﻿#region File Description
//-----------------------------------------------------------------------------
// ContineWithTask
//
// Copyright © 2013 Wave Coorporation. All rights reserved.
// Use is subject to license terms.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using System.Diagnostics;
using WaveEngine.Framework;
#endregion

namespace WaveEngine.Extensions.ITasks
{
    public class TaskNode : TaskBase
    {
        //IRunableTask wrappedTask;
        /// <summary>
        /// The wrapped task
        /// </summary>
        ITask wrappedTask;

        internal TaskNode(Scene scene, string taskName, ITask wrappedTask)
            : base(scene, taskName)
        {
            this.wrappedTask = wrappedTask;
            wrappedTask.Completed += this.performCompleted;
            //wrappedTask.Cancelled += this.onCancel;
            if (wrappedTask.TaskState != WaveEngine.Framework.Services.TaskState.None /*if the root task refernce is given*/
                && wrappedTask.TaskState != WaveEngine.Framework.Services.TaskState.Waiting /*if a leave reference is given*/)
            {
#if DEBUG
                throw new NotSupportedException("The wrapped task must be an unstarted root task");
#endif
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TaskNode" /> class.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="taskName">Name of the task.</param>
        /// <param name="wrappedTask">The wrapped task.</param>
        internal TaskNode(ITask parent, string taskName, ITask wrappedTask)
            : base(parent, taskName)
        {
            this.wrappedTask = wrappedTask;
            wrappedTask.Completed += this.performCompleted;
            //wrappedTask.Cancelled += this.onCancel;
            if (wrappedTask.TaskState != WaveEngine.Framework.Services.TaskState.None /*if the root task refernce is given*/
                && wrappedTask.TaskState != WaveEngine.Framework.Services.TaskState.Waiting /*if a leave reference is given*/)
            {
#if DEBUG
                throw new NotSupportedException("The wrapped task must be an unstarted root task");
#endif
            }
        }

        /// <summary>
        /// Ons the cancel.
        /// </summary>
        protected override void performCancel()
        {
            if(this.TaskState==WaveEngine.Framework.Services.TaskState.Running)
                this.wrappedTask.Cancel();

            base.performCancel();
        }

        /// <summary>
        /// Notifies the skip.
        /// </summary>
        protected override bool performSkip()
        {
            if (this.IsSkippable)
            {
                wrappedTask.Cancel();
                return base.performSkip();
            }
            else
            {
                return wrappedTask.TrySkip();
            }

        }

        /// <summary>
        /// Ons the run.
        /// </summary>
        [DebuggerStepThrough]
        protected override void performRun()
        {
            if (wrappedTask.TaskState != WaveEngine.Framework.Services.TaskState.Running)
                this.wrappedTask.Run();
        }

        /// <summary>
        /// Returns a <see cref="System.String" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String" /> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return "[" + base.ToString() + "->  " + wrappedTask.ToString() + "]";
        }

        /// <summary>
        /// Gets or sets the child tasks.
        /// </summary>
        /// <value>
        /// The child tasks.
        /// </value>
        /// <exception cref="System.NotImplementedException"></exception>
        public override IEnumerable<ITask> ChildTasks
        {
            get { yield return this.wrappedTask; }
        }
    }
}
